#ifndef GAME_H
#define GAME_H

#include "stdafx.h"
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <math.h>
#include <windows.h>		// Header File For Windows
#include <gl\gl.h>			// Header File For The OpenGL32 Library
#include <gl\glu.h>			// Header File For The GLu32 Library
//#include <gl\glaux.h>		// Header File For The Glaux Library
#include <list>

#include "games.h"
using namespace games;

#define BALL 1 //unique calllist identifier for the ball
#define BLOCK 2 //unique calllist identifier for the blocks
#define GRID 3 //unique calllist identifier for the grid

#define G 0.0008f //gravity constant
#define F 0.006f //friction constant
#define V 1.5 //desired velocity in y
#define V_STEP 1.01 //speed at which the ball aproaches linearly V in the off-axis direction (percent)
#define T 3.0f //terminal velocity

#define WIDTH 480 //width of the grid (in pixels)
#define HEIGHT 360 //height of the grid (in pixels)
#define ROWS 15 //rows in the game grid
#define COLS 12 //columns in the game grid
#define BLOCK_WIDTH       WIDTH/COLS
#define BLOCK_HEIGHT      HEIGHT/ROWS
#define HALF_BLOCK_WIDTH  BLOCK_WIDTH/2.0f
#define HALF_BLOCK_HEIGHT BLOCK_HEIGHT/2.0f
#define PADDING 2.5f //one half the distance between blocks
#define RADIUS 7.5f //radius or the ball
#define SLICES 20 //longitude lines on the ball
#define STACKS 20 //latitude lines on the ball
#define HIT_TIMEOUT 9

#define BLANK 0
#define BOMB_DOT 1
#define RED_DOT 2
#define BLUE_DOT 3
#define GREEN_DOT 4
#define PURPLE_DOT 5
#define YELLOW_DOT 6
#define GOAL 7
//backdrop numbers must be contiguous
#define BACKDROP1 8
#define BACKDROP2 9
#define BACKDROP3 10
#define BACKDROP4 11

#define TEX_COUNT 12

#define BLOCK_RATE 30
#define PAINT_RATE 10
#define BOMB_RATE 1
#define GRAY_RATE 5
#define BLOCKS_PER_LEVEL 30

class Game
{
public:
	~Game();
	float center[2]; //current location of the ball
	float vector[2]; //velocity vector of the ball
	float cur_cell[2]; // current grid cell the ball is in
	int   cell_quad[2]; // which quadrant of the cell the ball is in
	int axis; //axis in which velocity is a free variable 0 for x, 1 for y
	Block * grid[COLS][ROWS]; //game board
	games::Type type; //type for the ball (it's color)

	float boundary_x_pos; //edge of the map in the positive x direction
	float boundary_x_neg; //edge of the map in the negative x direction
	float boundary_y_pos; //edge of the map in the positive y direction
	float boundary_y_neg; //edge of the map in the negative y direction

	void init_game(int game_id); //sets up a new game from a given width and height;
	void end_game();
	bool playing;
	void update_score();
	int score;
	time_t last_hit;

	/*****************************************************
	+++++++++++++++++ MOVEMENT HANDLING ++++++++++++++++++
	*****************************************************/
	void handle_gravity(float theta); //moves ball without respect to collisions
	void handle_collisions(); //corrects center and velocity in response to collisions
	float * is_collision(int cell_x, int cell_y); // checks if there's a collision and returns normal
	void handle_reaction(int cell_x, int cell_y); // react to the collision
	void handle_bomb(int cell_x, int cell_y);
	void handle_boundaries(); //corrects center and velocity in response to boundaries
	void update_pos();

	/*****************************************************
	++++++++++++++++++ OBJECT CREATION +++++++++++++++++++
	*****************************************************/
	GLUquadricObj*	ball; //glu sphere
	int init_ball(); //sets up the ball as a gluQuadratic
	int init_block(); //sets up the block as a gluQuadratic
	int init_grid();
	void paint_backdrop();
	void draw_block();

	/*****************************************************
	+++++++++++++++++++ OPENGL HELPERS +++++++++++++++++++
	*****************************************************/
	void set_color(games::Type t, float a);
	void set_texture(games::Type t);
	void init_textures();
	int backdrop;

	/*****************************************************
	++++++++++++++++++ GRID MANAGEMENT +++++++++++++++++++
	*****************************************************/
	void set_grid(games::Box * level,int count,float ** start,int back);
	void set_block(games::Box box);
	void unset_block(int col,int row);
	void clear_grid();
	void rand_populate_grid();
	void rand_populate_span(int row,int col,int row_span,int col_span,Type type,int odds, bool replace = false);
	Mode mode;
	int types;

	

protected:
};


#endif